/**
 * @file Bench.cpp
 * @author BadFatCat0919 (543015378@qq.com)
 * @brief 工作台类
 */

#include "Bench.h"
#include "def.h"
#include <cstring>

int Bench::totalNumber = 0;

/**
 * @brief 初始化
 * @param id 工作台ID
 * @param type 工作台类型字符
 * @param x 横坐标格号
 * @param y 纵坐标格号
 */
void Bench::init(int id, char type, int x, int y) {
    this->id = id;
    this->type = type - '0';
    this->set(x, y);
    if(this->type == 8 || this->type == 9) { // 不生产货物的工作台无法购买
        this->buyLock = true;
    }
    std::memset(this->sellLock, 0, sizeof this->sellLock);
}

/**
 * @brief 设置工作台总数
 * @param number 工作台总数
 */
void Bench::setTotalNumber(int number) {
    totalNumber = number;
}

/**
 * @brief 获取工作台总数
 * @return const int& 工作台总数
 */
const int &Bench::getTotalNumber() {
    return totalNumber;
}

/**
 * @brief 可以出售
 * @param material 出售的物品类型
 * @param bench 工作台类型
 * @return true 可以出售
 * @return false 不可以出售
 */
bool Bench::canSell(int material, int bench) {
    return BENCH_MATERIAL[bench] & BIT(material);
}

/**
 * @brief 数据更新
 * @param type 工作台类型
 * @param coord_x 横坐标
 * @param coord_y 纵坐标
 * @param remainFrames 剩余生产时间(帧数)
 * @param materialStatus 原材料格状态
 * @param productStatus 产品格状态
 */
void Bench::refresh(int type, double coord_x, double coord_y, int remainFrames, int materialStatus, bool productStatus) {
    this->type = type;
    this->set(Coord(coord_x, coord_y));
    this->remainFrames = remainFrames;
    this->materialStatus = materialStatus;
    this->productStatus = productStatus;
}

/**
 * @brief 获取工作台ID
 * @return int 工作台ID
 */
int Bench::getID() {
    return this->id;
}

/**
 * @brief 是否符合生产条件
 * @return true 已符合
 * @return false 未符合
 */
bool Bench::isReady() {
    return this->materialStatus == BENCH_MATERIAL[this->type];
}

/**
 * @brief 获取产品格状态
 * @return true 有产品
 * @return false 无产品
 */
bool Bench::getProductStatus() {
    return this->productStatus;
}

/**
 * @brief 判断是否收购指定类型的原材料
 * @param materialType  原材料种类
 * @return true 收购
 * @return false 不收购
 */
bool Bench::isAccept(int materialType) {
    return Bench::canSell(materialType, this->type);
}

/**
 * @brief 判断是否还需要指定的原材料
 * @param materialType 原材料种类
 * @return true 还需要
 * @return false 不需要
 */
bool Bench::isNeed(int materialType) {
    return (BENCH_MATERIAL[this->type] ^ this->materialStatus) & BIT(materialType);
}

/**
 * @brief 获得已被填充的格口数
 * @return int 已被填充的格口数
 */
int Bench::getFilledNum() {
    int filled = 0;
    for(int i = 0; i < 8; i++) {
        if(this->isAccept(i)) {
            filled += !this->isNeed(i);
        }
    }
    return filled;
}

/**
 * @brief 获取工作台类型
 * @return int 工作台类型
 */
int Bench::getType() {
    return this->type;
}

/**
 * @brief 获取工作台生产物品类型
 * @return int 工作台生产物品类型
 */
int Bench::getProductType() {
    return BENCH_PRODUCT[getType()];
}

/**
 * @brief 获取工作台剩余生产帧数
 * @return int 剩余生产帧数
 */
int Bench::getRemainFrames() {
    return this->remainFrames;
}

/**
 * @brief 购买锁定
 */
void Bench::lockBuy() {
    this->buyLock = true;
}

/**
 * @brief 解除购买锁定
 */
void Bench::freeBuy() {
    this->buyLock = false;
}

/**
 * @brief 查询是否可以购买
 * @return true 可以购买
 * @return false 不可购买
 */
bool Bench::isBuyFree() {
    return !this->buyLock;
}

/**
 * @brief 出售锁定
 * @param type 货物类型
 */
void Bench::lockSell(int type) {
    if(this->type == 8 || this->type == 9) { // 工作台8和9可以随意出售
        return;
    }
    this->sellLock[type - 1] = true;
}

/**
 * @brief 解除出售锁定
 * @param type 货物类型
 */
void Bench::freeSell(int type) {
    this->sellLock[type - 1] = false;
}

/**
 * @brief 查询是否可以出售
 * @param type 货物类型
 * @return true 可以出售
 * @return false 可以出售
 */
bool Bench::isSellFree(int type) {
    if(type) {
        return !this->sellLock[type - 1];
    }
    for(int i = 0; i < 7; i++) {
        if(this->sellLock[i]) {
            return false;
        }
    }
    return true;
}
